/****************************************************************************
 * @file    : lin_api_appl.c
 * @author  : Nonosns MCU Team
 * @version : V2.0
 * @Date    : 2023/4/4
 * @brief   : lin stack file
 * @note
 * Copyright (C) 2023 Novosense All rights reserved.
 ****************************************************************************/

/*******************************************************************************
 * Include files
 *******************************************************************************/
#include <string.h>
#include "include.h"
#include "lin_define.h"
#include "lin_config.h"
#include "lin_api.h"
#include "lin_api_appl.h"
#include "DCM_driver.h"

/*******************************************************************************
 * definitions
 *******************************************************************************/

/*******************************************************************************
 * global  variables
 *******************************************************************************/

/*******************************************************************************
 * static  variables
 *******************************************************************************/
static l_bool g_updateLED = 1;        // update flag for signal "LED"
static l_bool g_updateKeyState = 1;   // update flag for signal "key_state"
static l_bool g_updateMotorState = 0; // update flag for signal "StepperMotorState"

/*******************************************************************************
********************************************************************************
* implementation of global  functions
*
* Those functions  have to be completed/modified  according the requirements
* of the  application.
********************************************************************************
*******************************************************************************/

#ifdef DEBUG
/************************************************************
 * @brief: see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
l_bool l_bool_rd_sss(void)
{
    return 0;
}

/************************************************************
 * @brief: see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
l_u8 l_u8_rd_sss(void)
{
    return 0;
}

/************************************************************
 * @brief: see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
l_u16 l_u16_rd_sss(void)
{
    return 0;
}

/************************************************************
 * @brief: see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @param <l_bool> v
 * @return <None>
 ************************************************************/
void l_bool_wr_sss(l_bool v)
{
}

/************************************************************
 * @brief: see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @param <l_bool> v
 * @return <None>
 ************************************************************/
void l_u8_wr_sss(l_u8 v)
{
}

/************************************************************
 * @brief: see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @param <l_bool> v
 * @return <None>
 ************************************************************/
void l_u16_wr_sss(l_u16 v)
{
}

/************************************************************
 * @brief: see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @param <l_u8> start
 * @param <l_u8> count
 * @param <l_u8> data
 * @return <None>
 ************************************************************/
void l_bytes_rd_sss(l_u8 start, l_u8 count, l_u8 *const data)
{
}

/************************************************************
 * @brief: see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @param <l_u8> start
 * @param <l_u8> count
 * @param <l_u8> data
 * @return <None>
 ************************************************************/
void l_bytes_wr_sss(l_u8 start, l_u8 count, const l_u8 *const data)
{
}

/************************************************************
 * @brief: see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
l_bool l_flg_tst_fff(void)
{
    return 0;
}

/************************************************************
 * @brief: see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
void l_flg_clr_fff(void)
{
}
#endif

/************************************************************
 * @brief: This function is called from RxTxStatusNotification() and sets the corresponding update flag,
           if the related signal has been changed.
 * @author: Nonosns MCU Team
 * @param <l_u8> *frame_array, the pointer to l_tmp_data_array that contains the frame data
          (see section "static variables" in lin_api.c)
 * @return <None>
 ************************************************************/
void l_flg_set_update_flags(l_u8 *frame_array)
{
    // Set update flags for the signals "LED" and "key_state"

    /* The frame PIDs (ID_13, ID_14, etc.) might be reconfigured meanwhile.
       Therefore the current g_nodeFramePIDTable[] is used (and not the initial PIDs)
       for comparison with the PID received from the LIN master. */
    /* set flag only if the signal has changed */
    if ((frame_array[0] == g_nodeFramePIDTable[LED_RESPONSE_FRAME]) &&
        (g_nodeConfigFrameTable[LED_RESPONSE_FRAME].var[0] != frame_array[1]))
    {
        g_updateLED = 1;
    }

    if (frame_array[0] == g_nodeFramePIDTable[KEY_REQUEST_FRAME])
    {
        g_updateKeyState = 1; // set flag, when the frame has been sent
    }

    if (frame_array[0] == g_nodeFramePIDTable[MOTOR_REQUEST_FRAME])
    {
        g_updateMotorState = 1;
    }
}

/************************************************************
 * @brief: This function is called from main and sets the corresponding update flag,
 *          if the related signal has been changed.
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
u16 angleAct;
u16 faultState;
void l_get_motor_pos_fault(void)
{
    l_irqmask irq_state = l_sys_irq_disable(); // disable all interruptsks
    angleAct = Get_AngleAct();                 // 获取实时角度值
    faultState = Get_FaultState();
    angleAct = (faultState << 12) + angleAct;

    g_nodeConfigFrameTable[MOTOR_RESPONSE_FRAME].var[0] = (uint8_t)(angleAct / 0xff);
    g_nodeConfigFrameTable[MOTOR_RESPONSE_FRAME].var[1] = (uint8_t)(angleAct % 0xff);
    g_nodeConfigFrameTable[MOTOR_RESPONSE_FRAME].var[2] = (uint8_t)(DCMotorVar.s16PosAct / 0xff);
    g_nodeConfigFrameTable[MOTOR_RESPONSE_FRAME].var[3] = (uint8_t)(DCMotorVar.s16PosAct % 0xff);
    g_nodeConfigFrameTable[MOTOR_RESPONSE_FRAME].var[4] = (uint8_t)(s16PosAdcMax / 0xff);
    g_nodeConfigFrameTable[MOTOR_RESPONSE_FRAME].var[5] = (uint8_t)(s16PosAdcMax % 0xff);
    g_nodeConfigFrameTable[MOTOR_RESPONSE_FRAME].var[6] = (uint8_t)(DCMotorVar.s16PosZeroAdc / 0xff);
    g_nodeConfigFrameTable[MOTOR_RESPONSE_FRAME].var[7] = (uint8_t)(DCMotorVar.s16PosZeroAdc % 0xff);

    l_sys_irq_restore(irq_state); // restore irqmask
}

/************************************************************
 * @brief: indicates whether the signal "LED" has been updated
           see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
l_bool l_flg_tst_LED(void)
{
    return g_updateLED;
}

/************************************************************
 * @brief: indicates whether the signal "pos" has been updated
           see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
l_bool l_flg_tst_Motor(void)
{
    return g_updateMotorState;
}

/************************************************************
 * @brief: clears the update flag for signal "LED"
           see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
void l_flg_clr_LED(void)
{
    g_updateLED = 0;
}

/************************************************************
 * @brief: clears the update flag for signal "Pos"
           see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
void l_flg_clr_Motor(void)
{
    g_updateMotorState = 0;
}

/************************************************************
 * @brief: extract the signal "Motor postion" from the corresponding frame buffer
 *         see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
Command_t CommandData;
Command_t t_rd_Command(void)
{

    CommandData.Mode = g_nodeConfigFrameTable[MOTOR_REQUEST_FRAME].var[0];
    CommandData.u8Command = g_nodeConfigFrameTable[MOTOR_REQUEST_FRAME].var[1];
    CommandData.s16Parameter1 = ((u16)g_nodeConfigFrameTable[MOTOR_REQUEST_FRAME].var[2]) * 0x100 + (u16)g_nodeConfigFrameTable[MOTOR_REQUEST_FRAME].var[3];
    CommandData.s16Patameter2 = ((u16)g_nodeConfigFrameTable[MOTOR_REQUEST_FRAME].var[4]) * 0x100 + (u16)g_nodeConfigFrameTable[MOTOR_REQUEST_FRAME].var[5];
    CommandData.u8Reserve = g_nodeConfigFrameTable[MOTOR_REQUEST_FRAME].var[6];
    CommandData.u8Crc = g_nodeConfigFrameTable[MOTOR_REQUEST_FRAME].var[7];
    return CommandData;
}

/************************************************************
 * @brief: extract the signal "LED" from the corresponding frame buffer
 *         see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
l_u8 l_u8_rd_LED(void)
{
    return g_nodeConfigFrameTable[LED_RESPONSE_FRAME].var[0];
}

/************************************************************
 * @brief: indicates whether the signal "key_state" has been updated
 *        see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
l_bool l_flg_tst_key_state(void)
{
    return g_updateKeyState;
}

/************************************************************
 * @brief: clears the update flag for signal "key_state"
 *        see LIN 2.0 specification, chapter "CORE API"
 * @author: Nonosns MCU Team
 * @return <None>
 ************************************************************/
void l_flg_clr_key_state(void)
{
    g_updateKeyState = 0;
}

/************************************************************
 * @brief: updates the signal "key_state" in the corresponding frame buffer
 * @author: Nonosns MCU Team
 * @param <l_u8> v
 * @return <None>
 ************************************************************/
void l_u8_wr_key_state(l_u8 v)
{
    l_irqmask irqState = l_sys_irq_disable(); // disable all interrupts

    g_nodeConfigFrameTable[KEY_REQUEST_FRAME].var[0] &= ~(BIT_0);    // change only the bits of the used signals
    g_nodeConfigFrameTable[KEY_REQUEST_FRAME].var[0] |= v & (BIT_0); // key_state, bit 0

    l_sys_irq_restore(irqState); //  restore irqmask
}
